<script setup>
import { ref,onMounted } from 'vue'
import Map from 'ol/Map'
import View from 'ol/View'
import TileLayer from 'ol/layer/Tile'
import { defaults as defaultControls,Zoom } from 'ol/control'
import {DragPan} from 'ol/interaction';
import {defaults as defaultInteractions} from 'ol/interaction.js';
import OSM from 'ol/source/OSM'
import { XYZ } from "ol/source.js";

const map = ref(null)
const mapRef = ref(null)

const changeEvent = () => {
  if (!map.value) return;
  //通用更改事件。当修订计数器增加时触发。
  map.value.on('changed',(e)=>{
    console.log(e)
  })
  // change:size事件
  //屏幕尺寸变化的回调
  map.value.on('change:size',(e)=>{
    console.log('size改变');
  })

  // change:view事件
  map.value.on('change:view', (event) => {
    console.log('view改变');
  });
  // change:target事件
  map.value.on('change:target', (event) => {
    console.log('target改变');
  });
  // change:layerGroup事件
  map.value.on('change:layerGroup', (event) => {
    console.log('target改变');
    //图层动态变化，图例动态变化
  });
}

const clickEvent = () => {
  if (!map.value) return;
  //点击事件
  map.value.on('click', (event) => {
    console.log('点击事件');
  });
  //双击事件，没有拖动
  map.value.on('dblclick', (event) => {
    console.log('dblclick');
  });

  //真正的单击，没有拖动和双击。请注意，此事件会延迟 250 毫秒，以确保它不是双击。
  map.value.on('singleclick', (event) => {
    console.log('singleclick');
  })

}

const errorEventHandler = () => {
  if (!map.value) return;
  //错误事件
  map.value.on('error', (event) => {
    console.log('error');
  });
}

const moveEventHandler = () => {
  if (!map.value) return;
  //地图开始移动事件
  map.value.on('movestart', (event) => {
    console.log('movestart ',event);
  })

  // 地图移动结束
  map.value.on('moveend', (event) => {
    console.log('moveend ',event);
  })
}

const  pointerEventHandler = ()=> {
  //地图触摸拖拽事件
  map.value.on('pointerdrag', (event) => {
    console.log('pointerdrag');
  });
  //地图触摸移动事件
  map.value.on('pointermove', (event) => {
    console.log('pointermove');
  });
};

// 图层事件
const postEventHandle = () => {
  //在渲染图层之前触发，没有设置上下文context
  map.value.on('precompose', (event) => {
    console.log('precompose');
  });
  //所有图层渲染完后触发，没有设置上下文context
  map.value.on('postcompose', (event) => {
    console.log('postcompose');
  });
  //地图渲染完成触发
  map.value.on('postrender', (event) => {
    console.log('postrender');
  });
}

// 渲染完成事件 可以用来 判断是否初始化完成图层
const renderEventHandler = () => {
  map.value.on('rendercomplete', (event) => {
    console.log('rendercomplete');
  })
}

const propertyEventHandler = () => {
  map.value.on('propertychange', (event) => {
    console.log('propertychange');
  })
}

const addMethodHnadler = ()=>{
  // 添加控件
  map.value.addControl(new Zoom());
  map.value.addControl(new DragPan())
  map.value.addLayer(new TileLayer({
    source: new OSM(),
    className: 'OpenStreetMap'
  }))

  map.value.on('click',()=>{
    console.log('调度事件并调用所有侦听此类型事件的侦听器');
    map.value.dispatchEvent('dblclick')
  })

  map.value.on('click',(event)=>{
    let layers = []
    //检测与视口上的像素相交的layer
    map.value.forEachFeatureAtPixel(event.pixel,
      (layer) => {
        console.log(event, layer)
        layers.push(layer)
      },
      {
        layerFilter: function (layer) {
          //图层过滤
          //图层加载了三层所以会有三个layer打印出来
          console.log(layer, layer.get('name'))
          return layer.get('name') === 'OpenStreetMap';
        },
        hitTolerance: 0,//以 css 像素为单位的命中检测容差。将检查给定位置周围半径内的像素的featrue。
        checkWrapped: true//将检查 +/- 1 世界宽度范围内的包裹几何图形
      }
    );
    console.log(layers,'layers')
    let features = []
    map.value.forEachFeatureAtPixel(event.pixel,
      (feature) => {
        console.log(event, feature)
        features.push(feature)
      },
      {
        layerFilter: function (layer) {
          //图层过滤
          return layer.get('name') === 'gz';
        },
        hitTolerance: 10,
        checkWrapped: true
      }
    );
    console.log(features,'features')
  })

  map.value.on('dblclick',()=>{
    console.log('双击')
  })
}

const getMethodHandler = ()=>{
  const mapVal = map.value;
  mapVal.on('singleclick',event => {
    const controls = mapVal.getControls();
    console.log(controls);
    //获取给定像素的投影坐标
    let coordinateFromPixel = mapVal.getCoordinateFromPixel(event.pixel);
    console.log(coordinateFromPixel)
    let eventCoordinate = mapVal.getEventCoordinate(event.originalEvent);
    console.log(eventCoordinate)
    //获取到当前视口的像素
    let eventPixel = mapVal.getEventPixel(event.originalEvent);
    console.log(eventPixel)
    let keys = mapVal.getKeys();
    console.log(keys);
    //获取到map的图层组
    let layerGroup = mapVal.getLayerGroup();
    console.log(layerGroup)
    //获取坐标的像素。这需要用户投影中的坐标并返回相应的像素
    let pixelFromCoordinate = mapVal.getPixelFromCoordinate([113.35275651421398, 23.12185264976067]);
    console.log(pixelFromCoordinate)
    let properties = mapVal.getProperties();
    console.log(properties)
    //获取此对象的版本号。每次修改对象时，其版本号都会增加。
    let revision = mapVal.getRevision();
    console.log(revision)
    // 修改对象
    mapVal.changed()
    console.log(mapVal.getRevision())
    //获取到map容器
    let target = mapVal.getTarget();
    console.log(target)
    //获取到map容器元素id
    let targetElement = mapVal.getTargetElement();
    console.log(targetElement)
    //获取到map的视口
    let viewport = mapVal.getViewport();
    console.log(viewport)

    mapVal.on('click',()=>{

    })
  })
}

const removeMethodHandler = ()=> {
  let zoom = new Zoom();
  map.value.addControl(zoom)
  let controls = map.value.getControls();
  let len=controls.getArray().length;
  let array = controls.getArray();
  console.log(map.value.getControls().getArray())
  for (let i = 0; i < len; i++) {
    const control = array[i];
    map.value.removeControl(control)

  }

  //从地图中删除给定的交互。
  //this.map.removeInteraction(interaction)

  // 从地图中删除给定的图层。
  let layers = map.value.getLayers();
  map.value.removeLayer(layers.getArray()[1])

  // 从地图中删除给定的叠加层。
  // this.map.removeOverlay(overlay)
}

const initMap = () => {
  map.value = new Map({
    target: 'map',
    // XYZ OSM 都是不同解码方式
    layers: [
      //图层按提供的顺序呈现
      // new TileLayer({
      //   source: new OSM() //加载图层数据的来源OpenStreetMap
      // }),
      new TileLayer({
        title: '天地图',
        source: new XYZ({url: "http://t4.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=d30d1c34260f2edc72b25f9985e2fd69"}),
        name: "tdtLayer",
        data: "aaa"
      })
    ],
    // 配置视图 和layers同时使用
    view: new View({
      center: [113.24981689453125, 23.126468438108688], //视图中心位置
      projection: "EPSG:4326", //指定投影
      zoom: 12   //缩放级别
    }),
    // 地图控件
    controls: defaultControls({
      attribution: true,//禁用右下角的地图属性组件
      rotate: false,//禁用旋转组件 alt+shift true旋转交互时会有一个旋转控件显示出来
      zoom: false, //禁用左上角缩放组件
    }),
    // 地图交互
    interactions: defaultInteractions({
      altShiftDragRotate: false,//是否允许按住alt+shift拖拽旋转
      doubleClickZoom: true,//是否允许双击缩放
      dragPan: true// 是否允许平面拖拽
    }),
    //同时加载的最大的瓦片数量，默认是16
    maxTilesLoading: 16,
    //光标必须移动的最小距离（以像素为单位）才能被检测为地图移动事件而不是单击
    moveTolerance: 5,
    // 物理像素与css像素分辨率比值
    pixelRatio: window.devicePixelRatio,

  })

  // 事件绑定
  // 绑定change事件
  // changeEvent();
  // 绑定click事件
  // clickEvent();
  // 错误事件
  // errorEventHandler();
  //   地图移动事件
  // moveEventHandler();
  //     地图触摸拖拽事件
  // pointerEventHandler();
  // 图层事件 是每一块瓦片图层的渲染事件 都会渲染一次
  // postEventHandle();
  // 渲染完成事件
  // renderEventHandler();
  // 属性修改事件
  // propertyEventHandler();
  // addMethodHnadler();
  // getMethodHandler();
  removeMethodHandler();
  // setTimeout(()=>{
  //   map.value.setSize(10)
  //   map.value.setProperties('aa','aa')
  //   map.value.setProperties('aa','bb')
  // },1000)
}

onMounted(() => {
  initMap()
})
</script>

<template>
  <div id="map" class="map" ref="mapRef"> </div>
</template>

<style scoped>
#map {
  width: 100%;
  height: 100%;
}
</style>